﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

// Source from Delay's (David Anson's) Blog
// http://blogs.msdn.com/b/delay/archive/2010/12/06/hash-for-the-holidays-managed-implementation-of-crc32-and-md5-algorithms-updated-new-release-of-computefilehashes-for-silverlight-wpf-and-the-command-line.aspx

namespace System.Security
{
    /// <summary>
    /// Implements a generic Queue that blocks callers of Dequeue when empty.
    /// </summary>
    /// <typeparam name="T">Type parameter</typeparam>
    class BlockingQueue<T> : Queue<T>
    {
        // Locking object
        private readonly object _lock = new object();

        /// <summary>
        /// Dequeues an item if present; blocks the calling thread otherwise.
        /// </summary>
        /// <returns>Dequeued item.</returns>
        public T BlockingDequeue()
        {
            lock (_lock)
            {
                // Block if queue is empty
                if (0 == Count)
                {
                    Monitor.Wait(_lock);
                }

                // Dequeue and return item
                return Dequeue();
            }
        }

        /// <summary>
        /// Enqueues the specified item and unblocks a calling thread if necessary.
        /// </summary>
        /// <param name="item">Item to enqueue.</param>
        public void UnblockingEnqueue(T item)
        {
            lock (_lock)
            {
                // Enqueue the item and unblock a waiting thread.
                Enqueue(item);
                Monitor.Pulse(_lock);
            }
        }
    }
}
